package userext

import (
	"context"
	"github.com/axengine/utils/hash"
	"github.com/pkg/errors"
	"time"
	"trusteva/app/rbac/model"

	"trusteva/app/rbac/internal/svc"
	"trusteva/app/rbac/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
)

type UserLoginLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewUserLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserLoginLogic {
	return &UserLoginLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *UserLoginLogic) UserLogin(req *types.UserLoginRo) (resp *types.UserLoginRsp, err error) {
	var u model.User
	if err := l.svcCtx.DB.WithContext(l.ctx).Where("Login=?", req.Login).
		First(&u).Error; err != nil {
		logx.Error("UserLogin", err)
		return nil, errors.New("用户名或密码错误")
	}

	// check password
	hashedPswd := hash.Keccak256Base64([]byte(req.Password + u.Salt))
	if hashedPswd != u.Password {
		return nil, errors.New("用户名或密码错误")
	}

	// 查询用户权限
	var (
		actions     = make(map[int]int)
		hasRootRole bool
	)

	for _, roleId := range u.Roles.Unmarshal() {
		var role model.RoleConfig
		if err := l.svcCtx.DB.WithContext(l.ctx).Where("Id=?", roleId).First(&role).Error; err != nil {
			return nil, err
		}
		if role.IsRoot == 1 {
			hasRootRole = true
			actions = make(map[int]int)
			break
		}

		var userActions []model.RoleMenuAction
		if err := l.svcCtx.DB.WithContext(l.ctx).Where("RoleId=?", roleId).Find(&userActions).Error; err != nil {
			return nil, err
		}
		for _, v := range userActions {
			actions[v.ActionId] = v.ActionId
		}
	}

	token, expireAt, err := l.svcCtx.JwtMid.GenToken(u.ID, u.Roles.Unmarshal(), hasRootRole, actions)
	if err != nil {
		return nil, err
	}

	resp = new(types.UserLoginRsp)
	resp.Token = token
	resp.ExpireAt = time.Unix(expireAt, 0).Format(time.RFC3339)
	return
}
